package com.xiaobai.java_core.socket;

import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Author 王天文
 * @Date 2024/12/15 17:02
 * @Description:
 */
@Slf4j
public class SocketServerBIO {

    // 服务端监听器端口
    private static final int SERVER_PORT = 15000;

    public static void main(String[] args) {

        ServerSocket serverSocket = null;
        try {
            // 服务端绑定监听器端口
            serverSocket = new ServerSocket(SERVER_PORT);
            log.info("服务端启动，等待客户端连接，监听端口：{}", SERVER_PORT);

            while (true) {
                try {
                    // 获取新的连接
                    Socket socket = serverSocket.accept();
                    log.info("客户端已连接，端口：{}", socket.getPort());

                    // 每个连接创建一个线程（可使用ThreadPoolTaskExecutor或ThreadPoolExecutor创建线程）
                    Thread connectThread = new Thread(new Runnable() {
                        @Override
                        public void run() {

                            String connectThreadName = Thread.currentThread().getName();
                            log.info("连接线程名称，{}", connectThreadName);

                            try {
                                // 按字节流方式读取数据
                                InputStream socketInputStream = socket.getInputStream();
                                int len;
                                byte[] data = new byte[1024 * 1024];
                                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                                while ((len = socketInputStream.read(data)) != -1) {
                                    byteArrayOutputStream.write(data, 0, len);
                                }
                                log.info("客户端消息：{}", new String(byteArrayOutputStream.toByteArray()));

                                // 客户端响应
                                String responseMsg = "客户端响应消息" + "_" + connectThreadName;
                                OutputStream socketOutputStream = socket.getOutputStream();
                                log.info("客户端响应消息：{}", responseMsg);
                                socketOutputStream.write(responseMsg.getBytes());

                                // 服务端结束写入
                                socket.shutdownOutput();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }

                        }
                    });
                    connectThread.start();

                    // 判断连接是否断开
                    if (socket.isClosed()) {
                        log.info("客户端连接已断开");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
